package com.cb2.algorithm.leetcode;

import java.util.Deque;
import java.util.LinkedList;

/**
 * <a href="https://leetcode.cn/problems/convert-bst-to-greater-tree/">把二叉搜索树转换为累加树(Convert BST to Greater Tree)</a>
 * <p>给出二叉 搜索 树的根节点，该树的节点值各不相同，请你将其转换为累加树（Greater Sum Tree），使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。</p>
 * <p>提醒一下，二叉搜索树满足下列约束条件：
 * <ul>
 *     <li>节点的左子树仅包含键 小于 节点键的节点。</li>
 *     <li>节点的右子树仅包含键 大于 节点键的节点。</li>
 *     <li>左右子树也必须是二叉搜索树。</li>
 * </ul>
 * </p>
 * <p>注意：本题和<a href='https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/'>1038. 从二叉搜索树到更大和树</a> 相同</p>
 * <p>
 * <b>示例：</b>
 * <pre>
 *  示例 1：
 *      输入：[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
 *                              4
 *                            /   \
 *                           1     6
 *                          / \   / \
 *                         0   2 5   7
 *                              \     \
 *                               3     8
 *      输出：[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
 *                              30(8+7+6+5+4)
 *                            /    \
 *                          36      21(8+7+6)
 *                         /  \    /  \
 *                       36   35  26   15(8+7)
 *                             \        \
 *                              33       8
 *
 *  示例 2：
 *      输入：root = [0,null,1]
 *      输出：[1,null,1]
 *
 *  示例 3：
 *      输入：root = [1,0,2]
 *      输出：[3,3,2]
 *
 *  示例 4：
 *      输入：root = [3,2,4,1]
 *      输出：[7,9,4,10]
 * </pre>
 * </p>
 * <p>
 * <b>提示：</b>
 * <ul>
 *     <li>树中的节点数介于 0 和 10^4 之间。</li>
 *     <li>每个节点的值介于 -10^4 和 10^4 之间。</li>
 *     <li>树中的所有值 互不相同 。</li>
 *     <li>给定的树为二叉搜索树。</li>
 * </ul>
 * </p>
 *
 * @author c2b
 * @see LC0538ConvertBstToGreaterTree_M 把二叉搜索树转换为累加树(Convert BST to Greater Tree)
 * @see LC1038BinarySearchTreeToGreaterSumTree_M 从二叉搜索树到更大和树(Binary Search Tree to Greater Sum Tree)
 * @since 2025/2/12 9:25
 */
public class LC0538ConvertBstToGreaterTree_M {
    static class Solution {
        public TreeNode convertBST(TreeNode root) {
            //return convertBSTByIteration(root);
            return convertBSTByRecursion(root);
        }

        private TreeNode convertBSTByIteration(TreeNode root) {
            // 中序遍历：右->根->左，变型：左->根->右
            Deque<TreeNode> helper = new LinkedList<>();
            TreeNode currNode = root;
            int sum = 0;
            while (!helper.isEmpty() || currNode != null) {
                while (currNode != null) {
                    helper.addLast(currNode);
                    currNode = currNode.right;
                }
                currNode = helper.removeLast();
                sum += currNode.val;
                currNode.val = sum;
                currNode = currNode.left;
            }
            return root;
        }

        int sum = 0;

        private TreeNode convertBSTByRecursion(TreeNode currNode) {
            if (currNode != null) {
                // 右
                convertBSTByRecursion(currNode.right);
                // 根
                sum += currNode.val;
                currNode.val = sum;
                // 左
                convertBSTByRecursion(currNode.left);
            }
            return currNode;
        }
    }

    public static void main(String[] args) {
        TreeNode root1 = new TreeNode(4);
        root1.left = new TreeNode(1);
        root1.right = new TreeNode(6);
        root1.left.left = new TreeNode(0);
        root1.left.right = new TreeNode(2);
        root1.right.left = new TreeNode(5);
        root1.right.right = new TreeNode(7);
        root1.left.right.right = new TreeNode(3);
        root1.right.right.right = new TreeNode(8);

        Solution solution = new Solution();
        Printer.printTreeNode(solution.convertBST(root1));
    }

}
